package com.py.framework.core.rest.support;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.py.framework.core.log.ExceptionLogger;

/**
 * restTemplate 服务实现
 *
 */
@Component
public class RestTemplateServiceImpl implements RestTemplateService {

	@Autowired
	private RestTemplate restTemplate;

	private ObjectMapper objectMapper = new ObjectMapper();

	public <T> T getForEntity(String url, Map<String, Object> map, Class<T> classz) {
		String result = restTemplate.getForObject(url, String.class, map);
		return this.resultForEntity(classz, result);

	}

	public <T> List<T> getForList(String url, Map<String, Object> map, Class<T> classes) {
		String result = restTemplate.getForObject(url, String.class, map);
		return this.resultForList(classes, result);

	}

	public <T> T postForEntity(String url, Object request, Map<String, Object> map, Class<T> classes) {
		String result = restTemplate.postForObject(url, request, String.class, map);
		return this.resultForEntity(classes, result);
	}
	

	public <T> List<T> postForList(String url, Object request, Map<String, Object> map, Class<T> classes) {
		String result = restTemplate.postForObject(url, request, String.class, map);
		return this.resultForList(classes, result);

	}

	@Override
	public <T> T postForEntity(String url, Object request, Class<T> classes) {
		Map<String, Object> map = new HashMap<String, Object>();
		return this.postForEntity(url, request, map, classes);
	}
	
	@Override
	public <T> List<T> postForList(String url, Object request, Class<T> classes) {
		Map<String, Object> map = new HashMap<String, Object>();
		return this.postForList(url, request, map, classes);
	}
	
	
	/**
	 * 将结果集JSON转化为实体
	 * @param classes
	 * @param result
	 * @return
	 */
	private <T> T resultForEntity(Class<T> classes, String result) {
		T t = null;
		try {
			if (StringUtils.isNotEmpty(result)) {
				objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
				t = objectMapper.readValue(result, classes);
			}
		} catch (IOException e) {
			ExceptionLogger.error(e);
			throw new RuntimeException("结果集转换出错");
		}
		return t;
	}
	
	/**
	 * 将结果集JSON转化为LIST
	 * @param classes
	 * @param result
	 * @return
	 */
	private <T> List<T> resultForList(Class<T> classes, String result) {
		List<T> list = null;
		try {
			if (StringUtils.isNotEmpty(result)) {
//				objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
				JavaType type = objectMapper.getTypeFactory().constructParametrizedType(List.class, List.class,classes);
				list = objectMapper.readValue(result, type);
			}
		} catch (IOException e) {
			ExceptionLogger.error(e);
			throw new RuntimeException("结果集转换出错");
		}
		return list;
	}
	
	
//	/**
//	 * 将结果集JSON转化为实体
//	 * 
//	 * @param <T>
//	 * 
//	 * @param classes
//	 * @param result
//	 * @return
//	 * @throws Exception
//	 */
//	private <T> RestServiceResult<T> resultForEntity(Class<T> classes, Class<T> subClass, String result) {
//
//		JavaType superType = objectMapper.getTypeFactory().constructParametrizedType(classes, classes,
//				subClass);
//		JavaType type = objectMapper.getTypeFactory().constructParametrizedType(RestServiceResult.class,
//				RestServiceResult.class, superType);
//		RestServiceResult<T> restServiceResult = new RestServiceResult<>();
//
//		try {
//			if (result != null && !"".equals(result)  ) {
//				objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
//				restServiceResult = objectMapper.readValue(result, type);
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//			throw new RuntimeException("结果集转换出错");
//		}
//		if (restServiceResult != null
//				&& restServiceResult.getStatus() != RestServiceResult.CODE_SUCCSUCCESS) {
//			throw new RuntimeException(restServiceResult.getErrorInfo());
//		}
//		return restServiceResult;
//	}
//
//	/**
//	 * 将结果集JSON转化为实体
//	 * 
//	 * @param <T>
//	 * 
//	 * @param classes
//	 * @param result
//	 * @return
//	 * @throws Exception
//	 */
//	private <T> RestServiceResult<T> resultForEntity(Class<T> classes, String result) {
//		JavaType type = objectMapper.getTypeFactory().constructParametrizedType(RestServiceResult.class,
//				RestServiceResult.class, classes);
//		RestServiceResult<T> restServiceResult = new RestServiceResult<>();
//
//		try {
//			if (result != null && !"".equals(result)  ) {
//				objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
//				restServiceResult = objectMapper.readValue(result, type);
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//			throw new RuntimeException("结果集转换出错");
//		}
//		if (restServiceResult != null
//				&& restServiceResult.getStatus() != RestServiceResult.CODE_SUCCSUCCESS) {
//			throw new RuntimeException(restServiceResult.getErrorInfo());
//		}
//		return restServiceResult;
//		
//	}
//
//	/**
//	 * 将结果集JSON转化为LIST
//	 * 
//	 * @param classes
//	 * @param result
//	 * @return
//	 * @throws Exception
//	 */
//	private <T> RestServiceResult<List<T>> resultForList(Class<T> classes, String result) {
//		JavaType listType = objectMapper.getTypeFactory().constructParametrizedType(List.class, List.class,
//				classes);
//		JavaType type = objectMapper.getTypeFactory().constructParametrizedType(RestServiceResult.class,
//				RestServiceResult.class, listType);
//		RestServiceResult<List<T>> restServiceResult = new RestServiceResult<>();
//		try {
//			if (result != null && !"".equals(result)) {
//				restServiceResult = objectMapper.readValue(result, type);
//			}
//		} catch (Exception e) {
//			throw new RuntimeException("结果集转换出错");
//		}
//		if (restServiceResult != null
//				&& restServiceResult.getStatus() != RestServiceResult.CODE_SUCCSUCCESS) {
//			throw new RuntimeException(restServiceResult.getErrorInfo());
//		}
//		return restServiceResult;
//	}

}